package cn.exrick.xboot.modules.activiti.controller.business;

import cn.exrick.xboot.base.XbootBaseController;
import cn.exrick.xboot.common.constant.ActivitiConstant;
import cn.exrick.xboot.common.utils.PageUtil;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.vo.PageVo;
import cn.exrick.xboot.common.vo.Result;
import cn.exrick.xboot.common.vo.SearchVo;
import cn.exrick.xboot.modules.activiti.dao.mapper.EventReportMapper;
import cn.exrick.xboot.modules.activiti.entity.ActBusiness;
import cn.exrick.xboot.modules.activiti.entity.business.EventReport;
import cn.exrick.xboot.modules.activiti.service.ActBusinessService;
import cn.exrick.xboot.modules.activiti.service.ActProcessService;
import cn.exrick.xboot.modules.activiti.service.business.EventReportService;
import cn.exrick.xboot.modules.activiti.vo.ProcessNodeVo;
import cn.exrick.xboot.modules.base.entity.Department;
import cn.exrick.xboot.modules.base.entity.Role;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.webSocket.MyHandler;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.socket.TextMessage;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author 李健
 */
@Slf4j
@RestController
@Api(description = "事件上报管理接口")
@RequestMapping("/xboot/eventReport")
@Transactional
public class EventReportController extends XbootBaseController<EventReport, String> {

    @Autowired
    private EventReportService eventReportService;

    @Override
    public EventReportService getService() {
        return eventReportService;
    }

    @Autowired
    private ActBusinessService actBusinessService;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private ActProcessService actProcessService;

    @Autowired
    private EventReportMapper eventReportMapper;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    MyHandler myHandler;

    @RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
    @ApiOperation(value = "多条件分页获取")
    public Result<Page<EventReport>> getByCondition(@ModelAttribute EventReport eventReport,@ModelAttribute SearchVo searchVo,@ModelAttribute PageVo pageVo){
        Page<EventReport> page = eventReportService.findByCondition(eventReport, searchVo, PageUtil.initPage(pageVo));
        for(EventReport obj: page.getContent()){
            // 关联流程表 查询关联流程状态和结果等信息
            if(StrUtil.isNotBlank(obj.getActBusinessId())){
                ActBusiness actBusiness = actBusinessService.get(obj.getActBusinessId());
                obj.setStatus(actBusiness.getStatus());
                obj.setResult(actBusiness.getResult());
                obj.setApplyTime(actBusiness.getApplyTime());
                obj.setRouteName(actBusiness.getRouteName());
                obj.setProcInstId(actBusiness.getProcInstId());
            }
        }
        return new ResultUtil<Page<EventReport>>().setData(page);
    }

    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ApiOperation(value = "添加关联流程")
    public Result<Object> add(@ModelAttribute EventReport eventReport,@RequestParam String procDefId){
        String userId = securityUtil.getCurrUser().getId();
        log.info("接收事件上报数据："+ eventReport.toString());
        log.info("接收事件流程模板："+ procDefId);
        //查询当前人所在部门
        User user = eventReportMapper.findUserDep(userId);
        //查询当前人角色
        Role role = null;
        try {
            role = eventReportMapper.findUserRole(userId);
        } catch (Exception e) {}
        List<User> listUser = eventReportService.findUsers(eventReport,userId,procDefId);

        //保存事件上报
        if(null!=role && role.getName().toString().equals("ROLE_第三方机构")){
            eventReport.setEventSource("第三方");
        }
        if(eventReport.getEventNum() == null || eventReport.getEventNum().equals("")){
            SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMddHHmmss" );
            String str = sdf.format(new Date());
            eventReport.setEventNum(str);
        }
        eventReport.setPhone(user.getMobile());
        eventReport.setApplyTime(new Date());
        EventReport obj = eventReportService.save(eventReport);

        // 保存至我的申请业务
        ActBusiness actBusiness = new ActBusiness();
        actBusiness.setUserId(userId);
        actBusiness.setProcDefId(procDefId);
        actBusiness.setTitle(obj.getEventNum());
        // 记录关联业务表ID
        actBusiness.setTableId(obj.getId());
        ActBusiness a = actBusinessService.save(actBusiness);
        // 记录关联流程状态表ID
        obj.setActBusinessId(a.getId());
        eventReportService.update(obj);

        //websocket向客户端推送数据
        myHandler.sendMessageToAllUsers(new TextMessage(""));

        //设置审批人员
        String[] str = new String[listUser.size()];
        for(int i = 0; i < listUser.size(); i++) {
            str[i] = listUser.get(i).getId();
        }

        //提交直接启动流程
        actBusiness = actBusinessService.get(actBusiness.getId());
        actBusiness.setTableId(actBusiness.getTableId());
        actBusiness.setAssignees(str);
        String processInstanceId = actProcessService.startProcess(actBusiness);
        actBusiness.setProcInstId(processInstanceId);
        actBusiness.setStatus(ActivitiConstant.STATUS_DEALING);
        actBusiness.setResult(ActivitiConstant.RESULT_DEALING);
        actBusiness.setApplyTime(new Date());
        actBusinessService.update(actBusiness);
        return new ResultUtil<Object>().setSuccessMsg("操作成功");
    }

    /**
     * 通过部门查询下一审批用户
     * @param depid
     * @return
     */
        @RequestMapping(value = "/selectDepNode/{depid}/{buttonType}/{procInstId}/{currentTask}", method = RequestMethod.GET)
    @ApiOperation(value = "通过部门查询下一审批用户")
    public Result<ProcessNodeVo> selectDepNode(@ApiParam("部门id") @PathVariable String depid,@PathVariable String buttonType,@PathVariable String procInstId,@PathVariable String currentTask){
        ProcessNodeVo node = new ProcessNodeVo();
        List<User> listUser = null;
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
        ProcessDefinitionEntity dfe = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(pi.getProcessDefinitionId());
        if(currentTask.toString().equals("镇级河长办") && buttonType.equals("0")){
            listUser = eventReportMapper.findDepUserCun(depid);
        }else if( currentTask.toString().equals("镇河长办") && buttonType.equals("0")){
            listUser = eventReportMapper.findDepUserCun(depid);
        } else{
            listUser = eventReportMapper.findDepUser(depid);
        }
        node.setUsers(listUser);
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }

    /**
     * 查询所有镇部门
     * @return
     */
    @RequestMapping(value = "/getdeps", method = RequestMethod.GET)
    @ApiOperation(value = "查询所有镇部门")
    public Result<ProcessNodeVo> getdeps(){
        ProcessNodeVo node = new ProcessNodeVo();
        List<Department> listDep = eventReportMapper.getdep();
        node.setDepartments(listDep);
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }
}
